package org.ala.tiktools.rpc.plugin.load_balance.eureka;

import org.ala.tiktools.logs.LoggerFactory;
import org.ala.tiktools.rpc.exception.RpcRuntimeException;
import org.ala.tiktools.rpc.plugin.load_balance.AbstractDynamicLoadBalance;
import org.ala.tiktools.rpc.plugin.node.NodeKey;
import org.ala.tiktools.tools.BeanTools;
import org.slf4j.Logger;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;

import java.util.*;

/**
 * 基于Eureka的LoadBalance
 * <p>  没30s刷一次节点列表
 *
 * @author ala
 * @date 2025-04-10 12:22
 */
public class EurekaLoadBalance extends AbstractDynamicLoadBalance {


    static Logger log = LoggerFactory.getLogger("rpc", "loadBalance");


    /**
     *  拉取节点信息
     *  <p> 有可能拉到空节点
     */
    protected Set<NodeKey> loadNodeKeyFromRemote(String group) {
        DiscoveryClient discoveryClient = null;
        try {
            discoveryClient = BeanTools.getBean(context, DiscoveryClient.class);
        } catch (Exception e) {
            log.error("[EurekaLoadBalance loadRpcNodeKeyByGroup] 拿不到 DiscoveryClient 类型的Bean，无法获取节点列表", e);
            throw new RpcRuntimeException("[EurekaLoadBalance loadRpcNodeKeyByGroup] 拿不到 DiscoveryClient 类型的Bean，无法获取节点列表", e);
        }

        List<ServiceInstance> ins = discoveryClient.getInstances(group);
        Set<NodeKey> nks = new HashSet<>();
        for (ServiceInstance in : ins) {
            String host = in.getHost();
            String sport = in.getMetadata().getOrDefault(AbstractDynamicLoadBalance.METADATA_PORT, "NULL");
            try {
            	int[] ports = parsePorts(sport);
            	for (int port : ports) {
            		NodeKey nk = NodeKey.build(host, port);
                    nks.add(nk);
            	}
            } catch (Exception e) {
                log.error("[EurekaLoadBalance loadRpcNodeKeyByGroup] 解析节点信息失败 group:{} host:{} port:{}", group, host, sport, e);
            }
        }
        return nks;
    }
}
